<script setup lang="ts">
const route = useRoute()
const segments = computed(() => ([] as string[]).concat(route.params.slug ?? []))
const url = computed(() => `/${segments.value.join('/')}`)
type Resource =
| { __typename: 'Repository'; resourcePath: string; nameWithOwner: string; defaultBranchRef: { name: string } | null }
| { __typename: 'User' | 'Organization'; resourcePath: string }
const { data } = await useAsyncData(
() => `resource-${url.value}`,
() =>
graphqlRequest<{ resource: Resource | null }>(
`
query ($url: String!) {
resource(url: $url) {
__typename
resourcePath
... on Repository {
nameWithOwner
defaultBranchRef {
name
}
}
}
}
`,
{ url: url.value }
),
{ watch: [url] }
)
const resource = computed(() => data.value?.resource ?? null)
const repo = computed(() => (resource.value?.__typename === 'Repository' ? resource.value : null))
const rest = computed(() => {
if (!resource.value) return []
const depth = resource.value.resourcePath.split('/').filter(Boolean).length
return segments.value.slice(depth)
})
const view = computed(() => {
const r = resource.value
if (!r) return null
if (r.__typename !== 'Repository') {
return rest.value.length ? null : { kind: 'owner' as const, login: r.resourcePath.slice(1) }
}
const [kind, gitRef, ...path] = rest.value
if (!kind) return { kind: 'repo-root' as const }
if (kind === 'tree' && gitRef) {
return { kind: 'tree' as const, repo: r.nameWithOwner, gitRef, path: path.join('/') }
}
if (kind === 'blob' && gitRef && path.length) {
return { kind: 'blob' as const, repo: r.nameWithOwner, gitRef, path: path.join('/') }
}
return null
})
async function redirect() {
if (!segments.value.length) {
await navigateTo('/repos')
} else if (view.value?.kind === 'repo-root' && repo.value?.defaultBranchRef) {
await navigateTo(`${repo.value.resourcePath}/tree/${repo.value.defaultBranchRef.name}`)
}
}
await redirect()
watch(view, redirect)
</script>
<template>
<OwnerView v-if="view?.kind === 'owner'" :login="view.login" />
<TreeView v-else-if="view?.kind === 'tree'" :repo="view.repo" :git-ref="view.gitRef" :path="view.path" />
<BlobView v-else-if="view?.kind === 'blob'" :repo="view.repo" :git-ref="view.gitRef" :path="view.path" />
<div v-else class="container">
<template v-if="repo && view?.kind === 'repo-root'">
<h2>{{ repo.nameWithOwner }}</h2>
<p>This repository has no branches yet.</p>
</template>
<p v-else>Not found.</p>
</div>
</template>